/*
 * Copyright (C) 2009 Teleca Poland Sp. z o.o. <android@teleca.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.cmcc.aregister.cs.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.RejectedExecutionException;

import com.cmcc.aregister.MyApplication;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;


/**
 * ImageView extended class allowing easy downloading of remote images
 * 
 * @author Lukasz Wisniewski
 */
public class RemoteImageView extends ImageView {

	/**
	 * Maximum number of unsuccesful tries of downloading an image
	 */
	private static int MAX_FAILURES = 3;

	public RemoteImageView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public RemoteImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public RemoteImageView(Context context) {
		super(context);
	}

	/**
	 * Remote image location
	 */
	private String mUrl;

	/**
	 * Currently successfully grabbed url
	 */
	private String mCurrentlyGrabbedUrl;

	/**
	 * Remote image download failure counter
	 */
	private int mFailure;

	/**
	 * Position of the image in the mListView
	 */
	private int mPosition;

	/**
	 * ListView containg this image
	 */
	private ListView mListView;
	/**
	 * GridView containg this image
	 */
	private GridView mGridView;
	/**
	 * Default image shown while loading or on url not found
	 */
	private Integer mDefaultImage;

	/**
	 * Loads image from remote location
	 * 
	 * @param url
	 *            eg. http://random.com/abz.jpg
	 */
	public void setImageUrl(String url) {

		if (mUrl != null
				&& mUrl.equals(url)
				&& (mCurrentlyGrabbedUrl == null || (mCurrentlyGrabbedUrl != null && !mCurrentlyGrabbedUrl
						.equals(url)))) {
			mFailure++;
			if (mFailure > MAX_FAILURES) {
				loadDefaultImage();
				return;
			}
		} else {
			mUrl = url;
			mFailure = 0;
		}

		ImageCache imageCache = MyApplication.getInstance()
				.getImageCache();
		if (imageCache.isCached(url)) {
			this.setImageBitmap(imageCache.get(url));
		} else {
			try {
				new DownloadTask().execute(url);
			} catch (RejectedExecutionException e) {
				// do nothing, just don't crash
			}
		}
	}
	/**
	 * Image cache, one for all activities and orientations
	 */
	private ImageCache mImageCache;
	/**
	 * Sets default local image shown when remote one is unavailable
	 * 
	 * @param resid
	 */
	public void setDefaultImage(Integer resid) {
		mDefaultImage = resid;
	}

	/**
	 * Loads default image
	 */
	private void loadDefaultImage() {
		if (mDefaultImage != null)
			setImageResource(mDefaultImage);
	}

	/**
	 * Loads image from remote location in the ListView
	 * 
	 * @param url
	 *            eg. http://random.com/abz.jpg
	 * @param position
	 *            ListView position where the image is nested
	 * @param listView
	 *            ListView to which this image belongs
	 */
	public void setImageUrl(String url, int position, ListView listView) {
		mPosition = position;
		mListView = listView;
		setImageUrl(url);
	}

	public void setImageUrl(String url, int position, GridView gridView) {
		mPosition = position;
		mGridView = gridView;
		setImageUrl(url);
	}

	/**
	 * Asynchronous image download task
	 * 
	 * @author Lukasz Wisniewski
	 */
	class DownloadTask extends AsyncTask<String, Void, String> {

		private String mTaskUrl;
		private Bitmap mBmp = null;

		@Override
		public void onPreExecute() {
			loadDefaultImage();
			super.onPreExecute();
		}

		@Override
		public String doInBackground(String... params) {

			mTaskUrl = params[0];
			InputStream stream = null;
			URL imageUrl;
			Bitmap bmp = null;

			try {
				imageUrl = new URL(mTaskUrl);
				try {
					stream = imageUrl.openStream();
					BitmapFactory.Options opts = new BitmapFactory.Options();
					// 这个isjustdecodebounds很重要
					opts.inJustDecodeBounds = true;
					// bmp = BitmapFactory.decodeStream(stream, null, opts);
					byte[] data = null;
					try {
						if (stream != null) {
							data = readStream(stream);
						}
						if (data != null) {
							bmp = BitmapFactory.decodeByteArray(data, 0,
									data.length, opts);
						}
					} catch (Exception e1) {
						e1.printStackTrace();
					}
					// 获取到这个图片的原始宽度和高度
					int picWidth = opts.outWidth;
					int picHeight = opts.outHeight;
					// System.out.println("picWidth===============" + picWidth
					// + "====picHeight====" + picHeight);
					// opts.inSampleSize = 1;
					// // 根据屏的大小和图片大小计算出缩放比例
					// if (picWidth > picHeight) {
					// if (picWidth > BaseActivity.screenWidth)
					// opts.inSampleSize = 3;
					// } else {
					// if (picHeight > BaseActivity.screenHeight)
					// opts.inSampleSize = 4;
					// }
					opts.inSampleSize = 1;
					// System.out.println("有没有缩放呢================="
					// + opts.inSampleSize);
					// 这次再真正地生成一个有像素的，经过缩放了的bitmap
					opts.inJustDecodeBounds = false;
					// bmp = BitmapFactory.decodeStream(stream, null, opts);
					if (data != null) {
						bmp = BitmapFactory.decodeByteArray(data, 0,
								data.length, opts);
					}
					// try {
					// stream = imageUrl.openStream();
					// bmp = BitmapFactory.decodeStream(stream);
					try {
						if (bmp != null) {
							// System.out.println("位图的宽====" + bmp.getWidth());
							mBmp = bmp;
							MyApplication.getInstance().getImageCache()
									.put(mTaskUrl, bmp);

						} else {
						}
					} catch (NullPointerException e) {
					}
				} catch (IOException e) {
				} finally {
					try {
						if (stream != null) {
							stream.close();
						}
					} catch (IOException e) {
					}
				}

			} catch (MalformedURLException e) {
				e.printStackTrace();
			}
			return mTaskUrl;
		}

		@Override
		public void onPostExecute(String url) {
			super.onPostExecute(url);

			// target url may change while loading
			if (!mTaskUrl.equals(mUrl)) {

				return;
			}

			Bitmap bmp = MyApplication.getInstance().getImageCache()
					.get(url);
			if (bmp == null) {
				RemoteImageView.this.setImageUrl(url);
			} else {

				// if image belongs to a list update it only if it's visible
				if (mListView != null)
					if (mPosition < mListView.getFirstVisiblePosition()
							|| mPosition > mListView.getLastVisiblePosition())
						return;
				if (mGridView != null) {
					if (mPosition < mGridView.getFirstVisiblePosition()
							|| mPosition > mGridView.getLastVisiblePosition())
						return;
				}
				RemoteImageView.this.setImageBitmap(bmp);
				mCurrentlyGrabbedUrl = url;
			}
		}

	};

	/*
	 * 得到图片字节流 数组大小
	 */
	private byte[] readStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			outStream.write(buffer, 0, len);
		}
		outStream.close();
		inStream.close();
		return outStream.toByteArray();
	}
}
